package top.xzxsrq.fileviewutils.download;

import cn.hutool.core.util.RuntimeUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import top.xzxsrq.pyncm.PyncmUtils;
import top.xzxsrq.utils.PathUtils;
import top.xzxsrq.utils.StringUtilsZX;
import top.xzxsrq.web.download.CommonD;
import top.xzxsrq.web.download.DownloadManager;
import top.xzxsrq.web.download.DownloadThread;
import top.xzxsrq.web.download.entity.PageInfo;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@Component
public class WangYiYunDownload extends CommonD {
    private static final String saveDir = "saveDir"; // 文件保存位置
    private static final String quality = "quality"; // 音质
    private static final String songOrPlaylist = "songOrPlaylist"; // 下载单曲还是歌单
    private static final String overwrite = "overwrite"; // 是否覆盖原有歌曲
    private static final String downloadId = "downloadId"; // 下载的id

    @Value("${wangyiyunxiazai.pyncm}")
    public void setPyncm(String pyncm) {
        PyncmUtils.pyncm = pyncm;
    }

    @Value("${wangyiyunxiazai.load}")
    public void setLoad(String load) {
        PyncmUtils.load = load;
    }

    @Override
    public void webRunFunc(String downloadTaskId, String userBasePath, JSONObject jsonObject) throws Exception {
        String saveDir = jsonObject.getString(WangYiYunDownload.saveDir);
        saveDir = PathUtils.pathResolve(userBasePath, saveDir);
        WangYiYunDownload wangYiYunDownload = new WangYiYunDownload();
        wangYiYunDownload.downloadTaskId = downloadTaskId;
        String string = jsonObject.getString(overwrite);
        if (StringUtilsZX.isBlank(string)) {
            string = "0";
        }
        String string1 = jsonObject.getString(songOrPlaylist);
        if (StringUtilsZX.isBlank(string1)) {
            string1 = "playlist";
        }
        String string2 = jsonObject.getString(quality);
        if (StringUtilsZX.isBlank(string2)) {
            string2 = "standard";
        }
        wangYiYunDownload.download(
                saveDir,
                string2,
                string1,
                string,
                jsonObject.getString(downloadId)
        );
    }

    @Override
    public String getDownloadType() {
        return "网易云下载";
    }

    private void download(
            String saveDir,
            String quality,
            String songOrPlaylist,
            String overwrite,
            String downloadId
    ) throws ExecutionException, InterruptedException {
        List<String> cmd = new LinkedList<>();
        if ("0".equals(overwrite)) {
            cmd.add("--no-overwrite");
        }
        cmd.add("--output");
        cmd.add(saveDir);
        cmd.add("--quality");
        cmd.add(quality);
        if ("playlist".equals(songOrPlaylist)) {
            cmd.add("\"playlist=" + downloadId + "\"");
        } else {
            cmd.add("\"https://music.163.com/\\#/song\\?id\\=" + downloadId + "\"\n");
        }
        WangYiYunDownloadDT wangYiYunDownloadDT = new WangYiYunDownloadDT();
        wangYiYunDownloadDT.setWangYiYunDownload(this);
        String[] pyncmCmd = PyncmUtils.getPyncmCmd(cmd.toArray(new String[]{}));
        wangYiYunDownloadDT.setCmds(pyncmCmd);
        wangYiYunDownloadDT.setDownloadId(this.downloadTaskId);
        wangYiYunDownloadDT.setSavePath(saveDir);
        wangYiYunDownloadDT.setPageInfo(new PageInfo());
        wangYiYunDownloadDT.setDownloadType(this.getDownloadType());
        Future<Void> submit = DownloadManager.submit(wangYiYunDownloadDT);
        // 阻塞主线程
        submit.get();
    }


    @Override
    public List<Map<Object, Object>> webRunFuncParams() {
        List<Map<Object, Object>> result = new LinkedList<>();
        result.add(webRunFuncParam(
                "prop",
                saveDir,
                "label",
                "保存到文件夹",
                "type",
                "SelectBasePath"
        ));
        result.add(webRunFuncParam(
                "prop",
                downloadId,
                "label",
                "下载的id",
                "type",
                "input",
                "placeholder",
                "歌单或者歌曲的id，playlist=7987387019"
        ));
        result.add(webRunFuncParam(
                "prop",
                quality,
                "label",
                "音质",
                "type",
                "select",
                "props",
                webRunFuncParam("options", webRunFuncParamList(
                        webRunFuncParam("label", "Hi-Res", "value", "hires"),
                        webRunFuncParam("label", "无损", "value", "lossless"),
                        webRunFuncParam("label", "较高", "value", "exhigh"),
                        webRunFuncParam("label", "标准", "value", "standard")
                )),
                "placeholder",
                "音频音质（高音质需要 CVIP）"
        ));
        result.add(webRunFuncParam(
                "prop",
                songOrPlaylist,
                "label",
                "下载单曲还是歌单",
                "type",
                "select",
                "props",
                webRunFuncParam("options", webRunFuncParamList(
                        webRunFuncParam("label", "歌单", "value", "playlist"),
                        webRunFuncParam("label", "歌曲", "value", "song")
                ))
        ));
        result.add(webRunFuncParam(
                "prop",
                overwrite,
                "label",
                "是否覆盖原有歌曲",
                "type",
                "select",
                "props",
                webRunFuncParam("options", webRunFuncParamList(
                        webRunFuncParam("label", "覆盖", "value", "1"),
                        webRunFuncParam("label", "不覆盖", "value", "0")
                ))
        ));
        return result;
    }

    @EqualsAndHashCode(callSuper = true)
    @Data
    @Log4j2
    public static class WangYiYunDownloadDT extends DownloadThread {
        private WangYiYunDownload wangYiYunDownload;
        private String[] cmds;

        @Override
        public void createProcess() {
            log.info("创建的命令为：{}：任务id：{}", Arrays.toString(cmds), downloadId);
            process = RuntimeUtil.exec(cmds);
        }

        /**
         * 设置获取子进程控制台的编码
         */
        @Override
        protected String setProcessOutStrCharsetName() {
            return "GBK";
        }

        @Override
        public void showProcessLog(String line) {
            log.info("{}:下载id：{}:{}", downloadType, downloadId, line);
            float v = PyncmUtils.downloadPer(line);
            if (this.pageInfo.getDownloadPer() < v) {
                this.pageInfo.setDownloadPer(v);
            }
        }

        @Override
        public JSONObject getDownloadInfo() {
            JSONObject result = new JSONObject();
            result.put("downloadTaskId", wangYiYunDownload.downloadTaskId);
            result.put("pageInfo", this.getPageInfo());
            return result;
        }
    }
}
